package tc.de.krawallmann.input;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;

/**
 * The class InputMap maps keys or buttons of keyboards or controllers to
 * several action Strings.
 * 
 * @author KrawallMann
 * @version 1.0
 */
public class InputMap extends HashMap<Integer, Collection<String>> {

	/** The constant serialVersionUID. */
	private static final long serialVersionUID = -5062339467504465372L;

	/**
	 * Checks if this String is mapped to any key or button.
	 * 
	 * @param action
	 *            the action String to be looked for
	 * @return true, if the String is mapped to a key or button
	 */
	public boolean contains(final String action) {
		for (final Collection<String> l : values()) {
			if (l.contains(action)) {
				return true;
			}
		}
		return false;
	}

	/**
	 * Gets the key for the specified action.
	 * 
	 * @param action
	 *            the action
	 * @return the key for the specified action
	 */
	public Integer getFirstKeyFor(final String action) {
		for (final java.util.Map.Entry<Integer, Collection<String>> en : entrySet()) {
			if (en.getValue().contains(action)) {
				return en.getKey();
			}
		}
		return -1;
	}

	public Collection<Integer> getKeysFor(final String action) {
		final List<Integer> ret = new ArrayList<Integer>();
		for (final java.util.Map.Entry<Integer, Collection<String>> en : entrySet()) {
			if (en.getValue().contains(action)) {
				ret.add(en.getKey());
			}
		}
		return ret;
	}

	/**
	 * Maps this action String to a key.
	 * 
	 * @param key
	 *            the key
	 * @param action
	 *            the action String
	 */
	public void put(final Integer key, final String action) {
		if (!containsKey(key)) {
			put(key, new HashSet<String>());
		}
		get(key).add(action);
	}

	/**
	 * Removes the mapping of this key to the specified action.
	 * 
	 * @param key
	 *            the key
	 * @param action
	 *            the action
	 */
	public void remove(final Integer key, final String action) {
		if (containsKey(key)) {
			get(key).remove(action);
			if (get(key).isEmpty()) {
				remove(key);
			}
		}
	}
}
